package com.ruoyi.game.service.impl;

import java.util.List;
import java.util.Objects;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.game.constants.Constants;
import com.ruoyi.game.domain.GameInfo;
import com.ruoyi.game.api.domin.GameUser;
import com.ruoyi.game.exception.PermissionException;
import com.ruoyi.game.service.IGameInfoService;
import com.ruoyi.game.service.IGameUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.game.mapper.GamePermissionMapper;
import com.ruoyi.game.domain.GamePermission;
import com.ruoyi.game.service.IGamePermissionService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 权限Service业务层处理
 *
 * @author qidian
 * @date 2022-05-06
 */
@Service
public class GamePermissionServiceImpl implements IGamePermissionService
{
    @Autowired
    private GamePermissionMapper gamePermissionMapper;

    @Autowired
    private IGameUserService gameUserService;

    @Autowired
    private IGameInfoService gameInfoService;

    /**
     * 查询权限
     *
     * @param id 权限主键
     * @return 权限
     */
    @Override
    public GamePermission selectGamePermissionById(Long id)
    {
        return gamePermissionMapper.selectGamePermissionById(id);
    }

    /**
     * 查询权限
     * 不指定用户id,则为当前登录用户
     *
     * @param gameId 游戏id
     * @param userId 用户id
     * @return 权限
     */
    @Override
    public GamePermission selectGamePermissionByGameIdAndUserId(Long gameId, Long userId)
    {
        return gamePermissionMapper.selectGamePermissionByGameIdAndUserId(gameId, this.initUserId(userId));
    }

    /**
     * 查询权限列表
     *
     * @param gamePermission 权限
     * @return 权限
     */
    @Override
    public List<GamePermission> selectGamePermissionList(GamePermission gamePermission)
    {
        return gamePermissionMapper.selectGamePermissionList(gamePermission);
    }

    /**
     * 新增权限
     *
     * @param gamePermission 权限
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertGamePermission(GamePermission gamePermission)
    {
        gamePermission.setCreateTime(DateUtils.getNowDate());
        gamePermission.setUsername(SecurityUtils.getUsername());
        gamePermission.setCreateBy(SecurityUtils.getUsername());

        gamePermission.setUserId(this.initUserId(gamePermission.getUserId()));

        // 先查询是否存在
        GamePermission selectGamePermission = this.selectGamePermissionByGameIdAndUserId(gamePermission.getGameId(), gamePermission.getUserId());
        // 存在修改绑定账号
        if (Objects.nonNull(selectGamePermission))
        {
            // 未解绑
            Assert.isTrue(StrUtil.isEmpty(selectGamePermission.getAccount()), () -> new PermissionException("存在账号绑定关系, 请先解绑"));

            selectGamePermission.setAccount(gamePermission.getAccount());
            return this.updateGamePermission(selectGamePermission);
        }
        GameUser gameUser = gameUserService.selectGameUserByUserId(SecurityUtils.getUserId());
        // 包站
        if (StrUtil.equals(Constants.IS_FREE, gameUser.getIsFree()))
        {
            gamePermission.setPermType(Constants.MAIL);
            return gamePermissionMapper.insertGamePermission(gamePermission);
        }
        GameInfo gameInfo = gameInfoService.selectGameInfoByGameId(gamePermission.getGameId());
        // vip对应金额
        Long vipPrice = StrUtil.equals(Constants.CHARGE, gamePermission.getPermType()) ? gameInfo.getVip1() : gameInfo.getVip2();
        // 用户扣除金币
        gameUserService.consumption(vipPrice, "开通[" + gameInfo.getGameName() + "]权限扣费");
        return gamePermissionMapper.insertGamePermission(gamePermission);
    }

    /**
     * 修改权限
     *
     * @param gamePermission 权限
     * @return 结果
     */
    @Override
    public int updateGamePermission(GamePermission gamePermission)
    {
        gamePermission.setUpdateTime(DateUtils.getNowDate());
        gamePermission.setUpdateBy(SecurityUtils.getUsername());
        return gamePermissionMapper.updateGamePermission(gamePermission);
    }

    /**
     * 批量删除权限
     *
     * @param ids 需要删除的权限主键
     * @return 结果
     */
    @Override
    public int deleteGamePermissionByIds(Long[] ids)
    {
        return gamePermissionMapper.deleteGamePermissionByIds(ids);
    }

    /**
     * 删除权限信息
     *
     * @param id 权限主键
     * @return 结果
     */
    @Override
    public int deleteGamePermissionById(Long id)
    {
        return gamePermissionMapper.deleteGamePermissionById(id);
    }

    /**
     * 判断是否存在对应权限, 并返回绑定账号
     *
     * @param gameId  游戏id
     * @param type 提交类型
     */
    @Override
    public String isPermissionGetAccount(Long gameId, String type)
    {
        GamePermission gamePermission = Assert.notNull(this.selectGamePermissionByGameIdAndUserId(gameId, null), () -> new PermissionException("您无对应操作权限, 请先进行开通"));

        // 邮件权限
        if (StrUtil.equals(Constants.MAIL, gamePermission.getPermType()))
        {
            return gamePermission.getAccount();
        }
        // 邮件提交
        if (StrUtil.equals(Constants.MAIL, type))
        {
            throw new PermissionException("您无对应操作权限, 请先进行开通");
        }
        return gamePermission.getAccount();
    }

    /**
     * 升级vip
     *
     * @param gameId 游戏id
     * @param userId 用户id
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int upgradeVip(Long gameId, Long userId)
    {
        userId = this.initUserId(userId);
        GamePermission gamePermission = Assert.notNull(this.selectGamePermissionByGameIdAndUserId(gameId, userId), () -> new PermissionException("您无对应操作权限, 请先进行开通"));
        // 已经是邮件最高权限
        Assert.isFalse(StrUtil.equals(Constants.MAIL, gamePermission.getPermType()), () -> new PermissionException("您已经是最高权限, 无需再次升级"));
        GameInfo gameInfo = gameInfoService.selectGameInfoByGameId(gamePermission.getGameId());
        // 升级需要补齐的金币
        Long vipPrice = gameInfo.getVip2() - gameInfo.getVip1();
        // 用户扣除金币
        gameUserService.consumption(vipPrice, "升级" + gameInfo.getGameName() + "]权限扣费");
        gamePermission.setPermType(Constants.MAIL);
        // 修改权限
        return this.updateGamePermission(gamePermission);
    }

    /**
     * 解绑账号
     *
     * @param gameId    游戏id
     * @param userId    用户id
     * @return  结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int unboundAccount(Long gameId, Long userId)
    {
        userId = this.initUserId(userId);
        GameUser gameUser = gameUserService.selectGameUserByUserId(userId);
        // 包站
        if (StrUtil.equals(Constants.IS_FREE, gameUser.getIsFree()))
        {
            GamePermission gamePermission = this.selectGamePermissionByGameIdAndUserId(gameId, userId);
            // 判断是否超过指定时间
            // TODO: 确认包站用户解绑指定时间
            Assert.isTrue(DateUtil.between(gamePermission.getUpdateTime(), DateUtil.date(), DateUnit.DAY, false) > 0, () -> new PermissionException("您解绑太频繁了, 请晚些再进行解绑"));
        }
        // 非包站
        else
        {
            // TODO: 确认用户扣除金币数量
            gameUserService.consumption(10L, "解绑账号");
        }
        return gamePermissionMapper.unboundAccount(gameId, userId);
    }

    /**
     * 初始化用户id
     * 无用户id,则为当前登录用户
     *
     * @param userId    用户id
     * @return  最终用户id
     */
    private Long initUserId(Long userId)
    {
        if (Objects.isNull(userId))
        {
            userId = SecurityUtils.getUserId();
        }
        return userId;
    }
}
